'use server';

import { signIn } from '@/auth';
import { AuthError } from 'next-auth';
import prisma from '@/app/lib/prisma';
import bcrypt from 'bcrypt';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import * as fs from 'node:fs/promises';
import path from 'path';

const FormSchema = z.object({
  id: z.string(),
  customerId: z.string({
    invalid_type_error: 'Please select a customer.',
  }),
  amount: z.coerce
    .number()
    .gt(0, { message: 'Please enter an amount greater than $0.' }),
  status: z.enum(['pending', 'paid'], {
    invalid_type_error: 'Please select an invoice status.',
  }),
  date: z.string(),
});

const CreateInvoice = FormSchema.omit({ id: true, date: true });
const UpdateInvoice = FormSchema.omit({ date: true, id: true });

// This is temporary
export type State = {
  errors?: {
    customerId?: string[];
    amount?: string[];
    status?: string[];
  };
  message?: string | null;
};
// 新增订单
export async function createInvoice(prevState: State, formData: FormData) {
  // Validate form fields using Zod
  const validatedFields = CreateInvoice.safeParse({
    customerId: formData.get('customerId'),
    amount: formData.get('amount'),
    status: formData.get('status'),
  });

  // If form validation fails, return errors early. Otherwise, continue.
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.',
    };
  }

  // Prepare data for insertion into the database
  const { customerId, amount, status } = validatedFields.data;
  const amountInCents = Number(amount) * 100;
  const date = new Date().toISOString().split('T')[0];

  // Insert data into the database
  try {
    await prisma.invoice.create({
      data: {
        customer_id: Number(customerId),
        amount: amountInCents,
        status,
        date,
      },
    });
  } catch (error) {
    console.log(error);
    // If a database error occurs, return a more specific error.
    return {
      message: '数据库错误：无法创建订单。',
    };
  }

  // Revalidate the cache for the invoices page and redirect the user.
  revalidatePath('/dashboard/invoices');
  redirect('/dashboard/invoices');
}
// 更新订单
export async function updateInvoice(
  id: string,
  prevState: State,
  formData: FormData,
) {
  const validatedFields = UpdateInvoice.safeParse({
    customerId: formData.get('customerId'),
    amount: formData.get('amount'),
    status: formData.get('status'),
  });

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Update Invoice.',
    };
  }

  const { customerId, amount, status } = validatedFields.data;
  const amountInCents = Number(amount) * 100;

  try {
    await prisma.invoice.update({
      where: {
        id: Number(id),
      },
      data: {
        customer_id: Number(customerId),
        amount: amountInCents,
        status: status,
      },
    });
  } catch (error) {
    return { message: 'Database Error: Failed to Update Invoice.' };
  }

  revalidatePath('/dashboard/invoices');
  redirect('/dashboard/invoices');
}
// 删除订单
export async function deleteInvoice(id: string) {
  try {
    await prisma.invoice.delete({
      where: {
        id,
      },
    });
    revalidatePath('/dashboard/invoices');
    return { message: 'Deleted Invoice' };
  } catch (error) {
    return { message: 'Database Error: Failed to Delete Invoice.' };
  }
}

// 邮箱、密码登录
export async function authenticate(
  prevState: string | undefined,
  formData: FormData,
) {
  try {
    const email = formData.get('email');
    const password = formData.get('password');
    await signIn('credentials', {
      email,
      password,
      redirectTo: '/user',
    });
  } catch (error) {
    if (error instanceof AuthError) {
      switch (error.type) {
        case 'CredentialsSignin':
          return 'Invalid credentials.';
        default:
          return 'Something went wrong.';
      }
    }
    throw error;
  }
}

// 注册
export async function register(
  prevState: string | undefined,
  formData: FormData,
) {
  try {
    const username = formData.get('username');
    const email = formData.get('email');
    const password = formData.get('password');
    const existUser = await prisma.user.findUnique({
      where: {
        email,
      },
    });

    if (existUser) {
      return {
        error: '当前邮箱已存在！',
      };
    }

    const hashedPassword = await bcrypt.hash(password as string, 10);

    return await prisma.user.create({
      data: {
        name: username,
        password: hashedPassword,
        email: email,
      },
    });
  } catch (error) {}
}

// 更新post
export async function updatePost(
  id: string,
  prevState: State,
  formData: FormData,
) {
  const title = formData.get('title') as string;
  const content = formData.get('content') as string;
  console.log(title, content);
  try {
    const rootDirectory = path.join(process.cwd(), 'app', 'posts');
    try {
      if (id) {
        // 删除旧文件
        const dir = Buffer.from(id, 'hex').toString('utf-8');
        const dirPath = path.join(rootDirectory, dir);
        const filePath = path.join(rootDirectory, dir, '/index.mdx');
        await fs.unlink(filePath);
        await fs.rmdir(dirPath);
      }
    } catch (error) {}
    try {
      // 创建新文件夹
      await fs.mkdir(path.join(rootDirectory, title));
    } catch (error) {}
    const filePath = path.join(rootDirectory, title, '/index.mdx');
    await fs.writeFile(filePath, content, {
      encoding: 'utf8',
    });
  } catch (error) {
    console.log(error);
    return { message: 'Database Error: Failed to Update Post.' };
  }

  revalidatePath('/dashboard/posts');
  redirect('/dashboard/posts');
}

// 删除post
export async function deletePost(id: string) {
  try {
    const rootDirectory = path.join(process.cwd(), 'app', 'posts');
    // 删除旧文件
    const dir = Buffer.from(id, 'hex').toString('utf-8');
    const dirPath = path.join(rootDirectory, dir);
    const filePath = path.join(rootDirectory, dir, '/index.mdx');
    await fs.unlink(filePath);
    await fs.rmdir(dirPath);
  } catch (error) {
    console.log(error);
    return { message: 'Database Error: Failed to Update Post.' };
  }

  revalidatePath('/dashboard/posts');
  redirect('/dashboard/posts');
}
